package com.tanhua.server.service;

import cn.hutool.core.collection.CollUtil;
import com.tanhua.autoconfig.template.OssTemplate;
import com.tanhua.commons.utils.Constants;
import com.tanhua.dubbo.api.MovementApi;
import com.tanhua.dubbo.api.UserInfoApi;
import com.tanhua.model.domain.UserInfo;
import com.tanhua.model.mongo.Movement;
import com.tanhua.model.vo.ErrorResult;
import com.tanhua.model.vo.MovementsVo;
import com.tanhua.model.vo.PageResult;
import com.tanhua.server.exception.BusinessException;
import com.tanhua.server.interceptor.UserHolder;
import org.apache.commons.lang.StringUtils;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
public class MovementsService {

    @DubboReference
    private MovementApi movementApi;

    @Autowired
    private OssTemplate ossTemplate;

    @DubboReference
    private UserInfoApi userInfoApi;

    @Autowired
    private RedisTemplate<String, String> redisTemplate;

    /**
     * 发布动态
     */
    public void publishMovement(Movement movement, MultipartFile[] imageContent) throws IOException {
        //判断发布动态的内容是否存在,不存在抛异常(动态数据为空)
        if (StringUtils.isEmpty(movement.getTextContent())) {
            throw new BusinessException(ErrorResult.contentError());
        }
        //获取当前登录的用户id
        Long userId = UserHolder.getUserId();
        //将文件内容上传到阿里云OSS，获取请求地址
        List<String> list = new ArrayList<>();
        for (MultipartFile multipartFile : imageContent) {
            String url = ossTemplate.upload(multipartFile.getOriginalFilename(), multipartFile.getInputStream());
            list.add(url);
        }
        //将数据封装到Movement对象
        movement.setUserId(userId);
        movement.setMedias(list);
        //调用API完成发布动态
        movementApi.publish(movement);
    }

    //查询个人动态
    public PageResult findByUserId(Long userId, int page, int pagesize) {
        //根据用户id，调用API查询个人动态内容（PageResult  -- Movement）
        PageResult pr = movementApi.findByUserId(userId, page, pagesize);
        //获取PageResult中的item列表对象
        List<Movement> items = (List<Movement>) pr.getItems();
        //非空判断
        if (items == null) {
            return pr;
        }
        //查询用户详细信息
        UserInfo userInfo = userInfoApi.findById(userId);
        List<MovementsVo> list = new ArrayList<>();
        //循环数据列表
        for (Movement item : items) {
            //一个Movement构建一个Vo对象
            MovementsVo vo = MovementsVo.init(userInfo, item);
            list.add(vo);
        }
        //构建返回值
        pr.setItems(list);
        return pr;
    }

    //好友动态
    public PageResult findFriendMovements(Integer page, Integer pagesize) {
        //获取当前用户id
        Long userId = UserHolder.getUserId();
        //查询数据列表
        List<Movement> items = movementApi.findFriendMovements(userId, page, pagesize);
        //非空判断
        if (CollUtil.isEmpty(items)) {
            return new PageResult();
        }
        //获取好友用户id
        List<Long> userIds = CollUtil.getFieldValues(items, "userId", Long.class);
        //循环数据列表
        Map<Long, UserInfo> infoMap = userInfoApi.findByIds(userIds, null);
        List<MovementsVo> vos = new ArrayList<>();
        for (Movement item : items) {
            //一个Movement构建一个Vo对象
            UserInfo userInfo = infoMap.get(item.getUserId());
            MovementsVo vo = MovementsVo.init(userInfo, item);
            vos.add(vo);
        }
        //构建返回值
        return new PageResult(page, pagesize, 0, vos);
    }

    //查询推荐动态
    public PageResult findRecommendMovements(Integer page, Integer pagesize) {
        //从redis中获取推荐数据
        String redisKey = Constants.MOVEMENTS_RECOMMEND + UserHolder.getUserId();
        String redisValue = redisTemplate.opsForValue().get(redisKey);
        //判断推荐数据是否存在,不存在随机10条,存在处理pid数据
        List<Movement> list = new ArrayList<>();
        if (StringUtils.isEmpty(redisValue)) {
            list = movementApi.randomMovements(pagesize);
        } else {
            String[] split = redisValue.split(",");
            //判断起始条数是否小于数组总数
            if ((page - 1) * pagesize < split.length) {
                List<Long> pids = Arrays.stream(split).skip((page - 1) * pagesize).limit(pagesize)
                        .map(e -> Long.valueOf(e)).collect(Collectors.toList());
                //获取动态详情
                list = movementApi.findByPids(pids);
            }
        }
        //获取好友用户id
        List<Long> userIds = CollUtil.getFieldValues(list, "userId", Long.class);
        //循环数据列表
        Map<Long, UserInfo> infoMap = userInfoApi.findByIds(userIds, null);
        List<MovementsVo> vos = new ArrayList<>();
        for (Movement movement : list) {
            UserInfo userInfo = infoMap.get(movement.getUserId());
            MovementsVo vo = MovementsVo.init(userInfo, movement);
            vos.add(vo);
        }
        //构建返回值
        return new PageResult(page, pagesize, 0, vos);
    }

    //根据动态id查询查询单条动态
    public MovementsVo findMovementById(String movementId) {
        //查询动态详情
        Movement movement = movementApi.findById(movementId);
        if (movement == null) {
            return null;
        }
        UserInfo userInfo = userInfoApi.findById(movement.getUserId());
        //返回vo对象
        return MovementsVo.init(userInfo, movement);
    }
}
